import asyncio

import paho.mqtt.client as mqtt
import paho.mqtt.enums as enums
from paho.mqtt.packettypes import PacketTypes
import time
from datetime import datetime
from usb import USBSerialTool

from ge101m_socket_client import GeSocketClient

class MQTTClient:

    TEST_TOPIC = "proline/web/v2/1/web00002"

    topics = [
        TEST_TOPIC,
    ]

    def __init__(self, broker, port, client_id="", username=None, password=None, keepalive=60 , usb_tool = None , socket_client = None):
        self.broker = broker
        self.port = port
        self.client_id = client_id
        self.username = username
        self.password = password
        self.keepalive = keepalive
        self.usb_tool:USBSerialTool = usb_tool
        self.socket_client: GeSocketClient = socket_client



        self.client = mqtt.Client(callback_api_version = enums.CallbackAPIVersion.VERSION2, client_id=client_id)
        if username and password:
            self.client.username_pw_set(username, password)

        self.client.on_connect = self.on_connect
        self.client.on_disconnect = self.on_disconnect
        self.client.on_message = self.on_message

    def on_connect(self, client, userdata, flags, reason, properties):
        if reason.packetType == PacketTypes.CONNACK:
            print("Connected successfully")
            # 订阅主题
            for topic in MQTTClient.topics:
                self.subscribe(topic)
        else:
            print(f"Connection failed: {reason}")

    def on_disconnect(self, client, userdata, flags, reason, properties):
        if reason.packetType == PacketTypes.DISCONNECT:
            print("Unexpected disconnection, trying to reconnect...")
            while True:
                try:
                    client.reconnect()
                    break
                except:
                    print("Reconnect failed, retrying in 3 seconds...")
                    time.sleep(3)

    def convert_date_format(self, date_str):
        # 解析输入的日期字符串
        date_obj = datetime.strptime(date_str, '%Y-%m-%d')
        # 转换为 'yymmdd' 格式
        return date_obj.strftime('%y%m%d')

    def on_message(self, client, userdata, msg):
        print(f"Received message '{msg.payload.decode()}' on topic '{msg.topic}' with QoS {msg.qos}")

        msg_content = msg.payload.decode()
        if "," not in msg_content:
            return
        parts = msg_content.split(",")
        print(f"----parts: {parts}")

        contents = {}
        for index,item in enumerate(parts):
            if index == 0 :
                # 生产批次号
                contents["4"] = f"(10){item}"
                contents["8"] = item
            if index == 1:
                #生产日期
                contents["5"] = f"(11){self.convert_date_format(item)}"
                contents["6"] = item
            if index == 2:
                # 有效期
                contents["3"] = f"(17){self.convert_date_format(item)}"
                contents["7"] = item
            if index == 3:
                # 袋DI
                contents["2"] = f"(01){item}"
            if index == 4:
                # 箱DI
                contents["2"] = f"(01){item}"

        contents["1"] = f"{contents['2']}{contents['3']}{contents['4']}{contents['5']}"

        parts = list()
        parts.append(contents["1"])
        parts.append(contents["2"])
        parts.append(contents["3"])
        parts.append(contents["4"])
        parts.append(contents["5"])
        parts.append(contents["6"])
        parts.append(contents["7"])
        parts.append(contents["8"])
        packets = self.usb_tool.wrap_packet(parts)
        content_str = packets.decode('utf-8')
        print(f"-----packets:{content_str}")
        # self.usb_tool.send_print_content(content_str)
        self.socket_client.send_data(content_str)

    def connect(self):
        self.client.connect(self.broker, self.port, self.keepalive)
        self.client.loop_start()

    def disconnect(self):
        self.client.loop_stop()
        self.client.disconnect()

    def publish(self, topic, payload, qos=2, retain=False):
        self.client.publish(topic, payload, qos, retain)

    def subscribe(self, topic, qos=2):
        self.client.subscribe(topic, qos)



async def main():

    port = '/dev/tty.usbserial-14530'
    usb_serial_tool = USBSerialTool(port, False)
    usb_serial_tool.open()

    server_ip = '192.168.1.253'
    server_port = 1030
    geSocketClient = GeSocketClient(server_ip, server_port)

    broker = "192.168.1.20"
    port = 1883
    client_id = "med_line_test" # 要保证唯一
    username = "admin"
    password = "taromed2024"
    keepalive = 10

    mqtt_client = MQTTClient(broker, port, client_id, username, password, keepalive=keepalive, usb_tool = usb_serial_tool, socket_client=geSocketClient)
    mqtt_client.connect()

    try:
        await geSocketClient.connect()
    except KeyboardInterrupt:
        mqtt_client.disconnect()



if __name__ == "__main__":
    asyncio.run(main())
